﻿{
  Provide Hash Calculator checker.
  
  Created by Arya Wiramukti R.
  + Currently it support MD5, and SHA1.
  + Support Unicode file name.

  Copyright (c) 2011 - 2013, Arya Wiramukti R. and others. All rights reserved.
  
  
  Agreements : 
   1. This Unit was released under Modified LGPL (follow Lazarus license).
   2. You must adding Author's name of this unit in your application credit, although this Unit might was modified by you.
   3. Author name MUST NOT BE DELETED from this Unit forever!

}

unit extELHash;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, lazutf8classes, MD5, SHA1;


// Export

function CalcMD5(const mFilePath: string): string;

function CalcSHA1(const mFilePath: string): string;


implementation


var
  iMD5: TMD5Digest;
  iSHA1: TSHA1Digest;

{============================================================
                      MD5 Calculator
=============================================================}

function StreamMD5(Stream: TFileStreamUTF8): TMD5Digest;
var
  Buf: array [0..1023] of byte;
  Context: TMD5Context;
  Count: longint;
begin
  Stream.Position := 0;
  MD5Init(Context);
  repeat
    Count := 1024;
    Count := Stream.Read(Buf, Count);
    if (Count > 0) then
      MD5Update(Context, Buf, Count);
  until (Count < 1024);
  MD5Final(Context, Result);
end;

function CalcMD5(const mFilePath: string): string;
var
  iostream: TFileStreamUTF8;

begin
  if FileExistsUTF8(mFilePath) then
  begin
    iostream := TFileStreamUTF8.Create(mFilePath, fmOpenRead);
    try
      iMD5 := StreamMD5(iostream);
    finally
      iostream.CleanupInstance;
      iostream.Free;
    end;
    Result := MD5Print(iMD5);
  end
  else
    Result := 'No such a file to calculate! Please choose one!';
end;

{============================================================
                   MD5 Calculator - END
=============================================================}

{============================================================
                    SHA1 Calculator
============================================================}

function StreamSHA1(Stream: TFileStreamUTF8): TSHA1Digest;
var
  Buf: array [0..1023] of byte;
  Context: TSHA1Context;
  Count: longint;
begin
  Stream.Position := 0;
  SHA1Init(Context);
  repeat
    Count := 1024;
    Count := Stream.Read(Buf, Count);
    if (Count > 0) then
      SHA1Update(Context, Buf, Count);
  until (Count < 1024);
  SHA1Final(Context, Result);
end;

function CalcSHA1(const mFilePath: string): string;
var
  iostream: TFileStreamUTF8;
begin
  if FileExistsUTF8(mFilePath) then
  begin
    iostream := TFileStreamUTF8.Create(mFilePath, fmOpenRead);
    try
      iSHA1 := StreamSHA1(iostream);
    finally
      iostream.CleanupInstance;
      iostream.Free;
    end;
    Result := SHA1Print(iSHA1);
  end
  else
    Result := 'No such a file to calculate! Please choose one!';
end;

{============================================================
                  SHA1 Calculator - END
============================================================}

end. 